package com.coder520.sync_learning.demo.mutex;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
 * 
 * @author asus
 *
 */
public class Mutex implements Lock{
	/**
	 * 静态内部类，自定义的同步器
	 * @author asus
	 *
	 */
	private static class Sync extends AbstractQueuedSynchronizer{
		/**
		 * 是否处于占用状态
		 */
		@Override
		protected boolean isHeldExclusively() {
			// TODO Auto-generated method stub
			return getState()==1;
		}
		/**
		 * 状态位0的时候，获取锁
		 */
		@Override
		protected boolean tryAcquire(int arg) {
			// TODO Auto-generated method stub
			if (compareAndSetState(0, 1)) {
				setExclusiveOwnerThread(Thread.currentThread());
				return true;
			}
			return false;
		}
		
		/**
		 * 释放锁。将状态重置为0
		 */
		@Override
		protected boolean tryRelease(int arg) {
			// TODO Auto-generated method stub
			if (getState()==0) {
				throw new IllegalMonitorStateException();
			}
			
			setExclusiveOwnerThread(null);
			
			setState(0);
			
			return true;
		}
		/**
		 * 返回一个condition 每一个condition都包含有一个condition队列
		 * @return
		 *	2018年6月12日
		 */
		@SuppressWarnings("unused")
		Condition newCondition() {
			return new ConditionObject();
		}
	}
	
	private final Sync sync=new Sync();

	
	@Override
	public void lock() {
		// TODO Auto-generated method stub
		sync.acquire(1);
	}

	@Override
	public void lockInterruptibly() throws InterruptedException {
		// TODO Auto-generated method stub
		sync.acquireInterruptibly(1);
	}

	@Override
	public boolean tryLock() {
		// TODO Auto-generated method stub
		return sync.tryAcquire(1);
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		// TODO Auto-generated method stub
		return sync.tryAcquireNanos(1, unit.toNanos(time));
	}

	@Override
	public void unlock() {
		// TODO Auto-generated method stub
		sync.release(1);
	}

	@Override
	public Condition newCondition() {
		// TODO Auto-generated method stub
		return sync.newCondition();
	}
	
	
	public boolean isLocked() {
		return sync.isHeldExclusively();
	}
	
	public boolean hasQueueThreads() {
		// TODO Auto-generated method stub
		return sync.hasQueuedThreads();
	}
	
	
}
